package com.dbg.cloud.acheron.plugins.oauth2.authserver.hydra.management.client.creation;
import com.dbg.cloud.acheron.plugins.oauth2.authserver.base.management.client.Client;
import com.dbg.cloud.acheron.plugins.oauth2.authserver.base.management.client.creation.ClientCreationOperation;
import com.dbg.cloud.acheron.plugins.oauth2.authserver.base.management.client.creation.ClientCreationResult;
import com.dbg.cloud.acheron.plugins.oauth2.authserver.hydra.management.client.HydraClient;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
@AllArgsConstructor
@Slf4j
final class ClientCreationOperationSimple implements ClientCreationOperation {
private final String clientCreationEndpointURL;
private final String ownAccessToken;
private final Client client;
private final RestTemplateBuilder restTemplateBuilder;
@Override
public ClientCreationResult result() throws TechnicalException {
final ClientCreationResult result;
final RestTemplate restTemplate = buildRestTemplate();
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + ownAccessToken);
final HydraClient hydraClient = new HydraClient(client);
final HttpEntity<HydraClient> hydraClientRequestHttpEntity = new HttpEntity<>(hydraClient, headers);
try {
final JSONResponse jsonResponse = restTemplate.postForObject(clientCreationEndpointURL,
hydraClientRequestHttpEntity, JSONResponse.class);
log.info("Hydra created client successfully: {}", jsonResponse.clientId());
result = new HydraClientCreationResult(jsonResponse); // NPE is possible, caught below
} catch (final HttpClientErrorException e) {
if (HttpStatus.BAD_REQUEST.equals(e.getStatusCode())) {
log.info("Bad request to Hydra: {}", e.getResponseBodyAsString());
return new ClientCreationResult.NoResult();
} else {
log.error("Hydra rejected the client creation request", e);
throw new TechnicalException();
}
} catch (final HttpServerErrorException e) {
log.error("Client creation request caused Hydra server error", e.getResponseBodyAsString());
throw new TechnicalException();
} catch (final Exception e) {
log.error("Could not create client in authorisation server", e);
throw new TechnicalException();
}
return result;
}
@SuppressWarnings("Duplicates")
private RestTemplate buildRestTemplate() {
final MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
final List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
supportedMediaTypes.add(MediaType.TEXT_PLAIN);
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
jsonMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
return restTemplateBuilder
.additionalMessageConverters(jsonMessageConverter)
.additionalMessageConverters(new FormHttpMessageConverter())
.build();
}
}